
#ifndef __dmIdList_h
#define __dmIdList_h

#include "dmObject.h"

class DMDB_BASE_API dmIdList : public dmObject
{
public:
  static dmIdList *New();

  void Initialize();

  // Description:
  int Allocate(const dmIdType sz, const int strategy=0);

  dmTypeMacro(dmIdList,dmObject);

  // Description:
  dmIdType GetNumberOfIds() {return this->NumberOfIds;};

  // Description:
  dmIdType GetId(const dmIdType i) {return this->Ids[i];};

  // Description:
  void SetNumberOfIds(const dmIdType number);

  // Description:
  void SetId(const dmIdType i, const dmIdType vtkid) {this->Ids[i] = vtkid;};

  // Description:
  void InsertId(const dmIdType i, const dmIdType vtkid);

  // Description:
  dmIdType InsertNextId(const dmIdType vtkid);

  // Description:
  dmIdType InsertUniqueId(const dmIdType vtkid);

  // Description:
  dmIdType *GetPointer(const dmIdType i) {return this->Ids + i;};

  // Description:
  dmIdType *WritePointer(const dmIdType i, const dmIdType number);

  // Description:
  void Reset() {this->NumberOfIds = 0;};

  // Description:
  // Free any unused memory.
  void Squeeze() {this->Resize(this->NumberOfIds);};

  // Description:
  void DeepCopy(dmIdList *ids);

  // Description:
  void DeleteId(dmIdType vtkid);

  // Description:
  dmIdType IsId(dmIdType vtkid);

  // Description:
  void IntersectWith(dmIdList* otherIds);

  // Description:
  dmIdType *Resize(const dmIdType sz);

  //BTX
  // This method should become legacy
  void IntersectWith(dmIdList& otherIds) {
    this->IntersectWith(&otherIds); };
  //ETX

protected:
  dmIdList();
  ~dmIdList();

  dmIdType NumberOfIds;
  dmIdType Size;
  dmIdType *Ids;

private:
  dmIdList(const dmIdList&);  // Not implemented.
  void operator=(const dmIdList&);  // Not implemented.
};

// In-lined for performance
inline void dmIdList::InsertId(const dmIdType i, const dmIdType vtkid)
{
  if (i >= this->Size)
    {
    this->Resize(i + 1);
    }
  this->Ids[i] = vtkid;
  if (i >= this->NumberOfIds)
    {
    this->NumberOfIds = i + 1;
    }
}

// In-lined for performance
inline dmIdType dmIdList::InsertNextId(const dmIdType vtkid)
{
  if ( this->NumberOfIds >= this->Size )
    {
    this->Resize(this->NumberOfIds+1);
    }
  this->Ids[this->NumberOfIds++] = vtkid;
  return this->NumberOfIds-1;
}

inline dmIdType dmIdList::IsId(dmIdType vtkid)
{
  dmIdType *ptr, i;
  for (ptr=this->Ids, i=0; i<this->NumberOfIds; i++, ptr++)
    {
    if ( vtkid == *ptr )
      {
      return i;
      }
    }
  return (-1);
}

#endif
